package java6699.lesson13;

/**
 * @program: java_zzx
 * @description:
 * @author: zzx
 * @create: 2022-11-28 10:29
 **/
public class BankSynchronized6699 {
    private static final BankAccount6699 account = new BankAccount6699("212106699", 1000);

    public static void main(String[] args) {
        Thread t1 = new Thread(BankSynchronized6699::bank6699, "会计");
        Thread t2 = new Thread(BankSynchronized6699::bank6699, "出纳");
        System.out.println(account.getBankID() + "账户上开始余额：" + account.getBalance() + "元");
        long l = System.currentTimeMillis();
        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long l1 = System.currentTimeMillis() - l;
        System.out.println(account.getBankID() + "账户上最终余额" + account.getBalance() + "元");
        System.out.println("处理银行账户的用时:" + (l1 * 0.001) + "秒");
    }

    public static void bank6699() {
        String name = Thread.currentThread().getName();
        String action = "";
        double money = 0, b = 0;
        if (name.equals("会计")) {
            money = 300;
            action = "存入";
        } else if (name.equals("出纳")) {
            money = -100;
            action = "取出";
        }
        synchronized (account) {
            for (int i = 1; i <= 3; i++) {
                // synchronized (this)  同步代码块，为块内代码加锁，只允许一个线程使用块内代码。
                // synchronized (account) 能达到同步效果，因为两个线程共享account，是同一个对象，可以实现同步
                // synchronized (account) 不能达到同步效果，因为两个线程的name不是同一个对象，无法实现同步
                b = account.getBalance() + money;
                System.out.println(name + action + Math.abs(money));
                account.setBalance(b);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                account.setBalance(b);
            }
        }
    }
}

class BankAccount6699 {
    private String bankID;
    private double balance;

    public BankAccount6699(String bankID, double balance) {
        this.bankID = bankID;
        this.balance = balance;
    }

    public String getBankID() {
        return bankID;
    }

    public void setBankID(String bankID) {
        this.bankID = bankID;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }
}
